How to interface with TCGA https://bioconductor.org/packages/devel/bioc/vignettes/TCGAbiolinks/inst/doc/index.html https://bioconductor.org/packages/release/workflows/vignettes/TCGAWorkflow/inst/doc/TCGAWorkflow.html#Environment

Loading the annotation file:

data("IlluminaHumanMethylationEPICanno.ilm10b4.hg19")
anno <- getAnnotation(IlluminaHumanMethylationEPICanno.ilm10b4.hg19)
load("/Users/adiallo/Desktop/Dartmouth/Christiansen_lab/CF_Project/Methylation/Annotation/EPIC.hg19.manifest.RDATA")
attach(annotation)
manifest <- getManifest(IlluminaHumanMethylationEPICmanifest)

Loading the data and metadata information

targets <- read.csv("/Users/adiallo/Desktop/Thesis/Data_Documents/dm_57_samples.csv")
targets$patient <- paste(targets$Sentrix_ID,targets$Sentrix_Position,sep="_")
rownames(targets) <- targets$patient
targets$SampleID<- targets$patient

targets_expanded <- read.csv("/Users/adiallo/Desktop/Thesis/Data_Documents/data_all.csv")
targets_expanded$patient <- paste(targets$Sentrix_ID,targets$Sentrix_Position,sep="_")
rownames(targets_expanded) <- targets_expanded$patient
targets_expanded$SampleID<- targets_expanded$patient
targets = targets_expanded
idat = "/Users/adiallo/Desktop/Thesis/Data_Documents/All_Data/DNA_Methylation/dm_data/no_match/"
RGset_32 = read.metharray.exp("/Users/adiallo/Desktop/Thesis/Data_Documents/All_Data/DNA_Methylation/dm_data/no_match/idats/",recursive = TRUE) 
#RGset_25 = openSesame(idat , func = getBetas) 
RGset_25 = read.metharray.exp("/Users/adiallo/Desktop/Thesis/Data_Documents/All_Data/DNA_Methylation/dm_data/no_match/25_samples/",recursive = TRUE) 

Normalize my Data

Noob_25_m = preprocessNoob(RGset_25)
Noob_32_m = preprocessNoob(RGset_32)

Getting the beta values

Betas_25<-getBeta(Noob_25_m)
Betas_32<-getBeta(Noob_32_m)
Betas_25<- sesame::betasCollapseToPfx(Betas_25)
#Betas_32<- sesame::betasCollapseToPfx(Betas_32)
colnames(Betas_25) = colnames(Noob_25_m)
DH_CRC_Betas <- merge(Betas_25, Betas_32, by = "row.names")
rownames(DH_CRC_Betas) <- DH_CRC_Betas$Row.names
DH_CRC_Betas <- DH_CRC_Betas[,-1] 

Running EpiDish to obtain Fibroblast information

# Define the beta matrix and reference matrix
beta_matrix <- DH_CRC_Betas  # Your dataset
ref_matrix <- centEpiFibIC.m  # Reference matrix for EpiDISH (e.g., centEpiFibIC.m)

# Run EpiDISH
epidish_results <- epidish(beta.m = beta_matrix, ref.m = ref_matrix, method = "RPC")

# Extract the estimated cell type proportions
cell_type_proportions <- epidish_results$estF

# Convert the matrix to a data frame and scale proportions to percentages
cell_type_proportions_df <- as.data.frame(cell_type_proportions) * 100

# Add SampleID as a column from the row names
cell_type_proportions_df$SampleID <- rownames(cell_type_proportions)

# Inspect the results
head(cell_type_proportions_df)

Running HiTIMED to generate cell type proportions

HiTIMED_result<-HiTIMED_deconvolution(DH_CRC_Betas,"COAD",5,"tumor")
snapshotDate(): 2024-04-29
see ?HiTIMED and browseVignettes('HiTIMED') for documentation
loading from cache
HiTIMED_result$SampleID <- rownames(HiTIMED_result)

HiTIMED_result_immune<-HiTIMED_deconvolution(DH_CRC_Betas,"COAD",2,"tumor")
snapshotDate(): 2024-04-29
see ?HiTIMED and browseVignettes('HiTIMED') for documentation
loading from cache
HiTIMED_result_immune$SampleID <- rownames(HiTIMED_result)

Get GTEx data


Betas_GTEx = readRDS("/Users/adiallo/Desktop/Thesis/Data_Documents/All_Data/DNA_Methylation/dm_data/GTEx/GTEx_samples.rds")
targets_GTEx <- read.csv("/Users/adiallo/Desktop/Thesis/Data_Documents/All_Data/DNA_Methylation/dm_data/GTEx/targets.csv")
targets_GTEx$patient <- targets_GTEx$Filename
rownames(targets_GTEx) <- targets_GTEx$patient
targets_GTEx$SampleID<- targets_GTEx$patient

# --- Harmonize CpGs ---
common_cpgs_GTEx <- intersect(rownames(Betas_GTEx), rownames(centEpiFibIC.m))
betas_GTEx_filtered <- Betas_GTEx[common_cpgs_GTEx, ]
ref_filtered_GTEx <- centEpiFibIC.m[common_cpgs_GTEx, ]

# --- Run EpiDISH ---
epidish_GTEx <- epidish(beta.m = betas_GTEx_filtered, ref.m = ref_filtered_GTEx, method = "RPC")
cell_props_GTEx <- as.data.frame(epidish_GTEx$estF) * 100
cell_props_GTEx$SampleID <- rownames(cell_props_GTEx)

# Optional: Merge with metadata
cell_props_GTEx <- merge(cell_props_GTEx, targets_GTEx, by = "SampleID")

HiTIMED_result_GTEx<-HiTIMED_deconvolution(Betas_GTEx,"COAD",h = 5,"tumor")
snapshotDate(): 2024-04-29
see ?HiTIMED and browseVignettes('HiTIMED') for documentation
loading from cache
HiTIMED_result_GTEx$SampleID <- rownames(HiTIMED_result_GTEx)

HiTIMED_result_immune_GTEx<-HiTIMED_deconvolution(Betas_GTEx,"COAD",h = 2,"tumor")
snapshotDate(): 2024-04-29
see ?HiTIMED and browseVignettes('HiTIMED') for documentation
loading from cache
HiTIMED_result_immune_GTEx$SampleID <- rownames(HiTIMED_result_GTEx)

Get TCGA data

tcga.data <- readRDS("/Users/adiallo/Desktop/Thesis/Data_Documents/All_Data/DNA_Methylation/dm_data/TCGA/TCGA_data.rds")
tcga.dnam <- tcga.data[["dnam"]]
tcga.pheno <- tcga.data[["pheno"]]
tcga.cell <- tcga.data[["cell_types"]]
msi_dat<-readRDS("/Users/adiallo/Desktop/Thesis/Data_Documents/All_Data/DNA_Methylation/dm_data/TCGA/msi_tcga.rds")
tcga.cell$COAD_Deconv1#$MSS

tcga.cell$COAD_Deconv2#MASS

tcga_T = t(tcga.dnam)
library(ggplot2)
library(dplyr)
library(tidyr)
library(ggpubr)

# ---- Function to Reshape Data ----
extract_subset <- function(df, source_label, cell_types = c("CD8T", "Tumor", "Epithelial")) {
  df %>%
    select(all_of(cell_types), SampleID) %>%
    pivot_longer(-SampleID, names_to = "CellType", values_to = "Proportion") %>%
    mutate(Source = source_label)
}

# ---- Combine Datasets ----
df_DH <- extract_subset(HiTIMED_result, "DH")
df_GTEx <- extract_subset(HiTIMED_result_GTEx, "GTEx")
df_TCGA <- extract_subset(HiTIMED_result_TCGA, "TCGA")

combined_df <- bind_rows(df_DH, df_GTEx, df_TCGA)

# ---- Define comparisons ----
comparisons <- list(c("DH", "GTEx"), c("DH", "TCGA"))

# ---- Boxplot with Significance Annotations ----
ggplot(combined_df, aes(x = Source, y = Proportion, fill = Source)) +
  geom_boxplot(outlier.shape = NA, width = 0.7) +
  facet_wrap(~ CellType, scales = "free_y") +
  stat_compare_means(comparisons = comparisons, method = "wilcox.test",
                     label = "p.signif", hide.ns = TRUE) +
  scale_fill_brewer(palette = "Set1") +
  labs(title = "Cell Type Proportions Across Datasets",
       y = "Estimated Proportion",
       x = "Dataset") +
  theme_minimal(base_size = 14) +
  theme(strip.text = element_text(size = 14),
        axis.text.x = element_text(angle = 30, hjust = 1))

library(ggplot2)
library(dplyr)
library(tidyr)
library(ggpubr)

# ---- Function to Extract Cell Types ----
extract_subset <- function(df, source_label, cell_types = c("CD8T", "Tumor", "Epithelial")) {
  df %>%
    select(all_of(cell_types), SampleID) %>%
    pivot_longer(-SampleID, names_to = "CellType", values_to = "Proportion") %>%
    mutate(Source = source_label)
}

# ---- Combine Only DH and GTEx ----
df_DH <- extract_subset(HiTIMED_result, "DH")
df_GTEx <- extract_subset(HiTIMED_result_GTEx, "GTEx")

combined_df <- bind_rows(df_DH, df_GTEx)

# ---- Define Comparisons ----
comparisons <- list(c("DH", "GTEx"))

# ---- Plot ----
ggplot(combined_df, aes(x = Source, y = Proportion, fill = Source)) +
  geom_boxplot(outlier.shape = NA, width = 0.7) +
  facet_wrap(~ CellType, scales = "free_y") +
  stat_compare_means(comparisons = comparisons, method = "wilcox.test",
                     label = "p.signif", hide.ns = TRUE) +
  scale_fill_brewer(palette = "Set1") +
  labs(title = "Comparison of Cell Type Proportions: DH vs GTEx",
       y = "Estimated Proportion",
       x = "Dataset") +
  theme_minimal(base_size = 14) +
  theme(strip.text = element_text(size = 14),
        axis.text.x = element_text(angle = 30, hjust = 1))

library(ggplot2)
library(dplyr)
library(tidyr)
library(ggpubr)

# ---- Function to Extract HiTIMED Cell Types ----
extract_subset_hitimed <- function(df, source_label, cell_types = c("CD8T", "Tumor", "Epithelial")) {
  df %>%
    select(all_of(cell_types), SampleID) %>%
    pivot_longer(-SampleID, names_to = "CellType", values_to = "Proportion") %>%
    mutate(Source = source_label)
}

# ---- Extract HiTIMED Results for DH and GTEx ----
df_DH_hitimed <- extract_subset_hitimed(HiTIMED_result, "DH")
df_GTEx_hitimed <- extract_subset_hitimed(HiTIMED_result_GTEx, "GTEx")

# ---- Function to Extract Fibroblast Estimates from EpiDISH/EpiScore ----
extract_subset_fib <- function(epi_df, source_label) {
  epi_df %>% 
    select(Fib, SampleID) %>% 
    pivot_longer(-SampleID, names_to = "CellType", values_to = "Proportion") %>% 
    mutate(Source = source_label)
}

# ---- Extract Fibroblast Results for DH and GTEx ----
df_DH_fib <- extract_subset_fib(cell_type_proportions_df, "DH")
df_GTEx_fib <- extract_subset_fib(cell_props_GTEx, "GTEx")

# ---- Combine All Results ----
combined_df <- bind_rows(df_DH_hitimed, df_GTEx_hitimed, df_DH_fib, df_GTEx_fib)

# ---- Define Comparisons (DH vs GTEx for each cell type) ----
comparisons <- list(c("DH", "GTEx"))

# ---- Plot: Faceted Boxplots by CellType ----
ggplot(combined_df, aes(x = Source, y = Proportion, fill = Source)) +
  geom_boxplot(outlier.shape = NA, width = 0.7) +
  facet_wrap(~ CellType, scales = "free_y") +
  stat_compare_means(comparisons = comparisons, method = "wilcox.test",
                     label = "p.signif", hide.ns = TRUE) +
  scale_fill_brewer(palette = "Set1") +
  labs(title = "Comparison of Cell Type Proportions: DH vs GTEx",
       y = "Estimated Proportion (%)",
       x = "Dataset") +
  theme_minimal(base_size = 14) +
  theme(strip.text = element_text(size = 14),
        axis.text.x = element_text(angle = 30, hjust = 1))

For obtaining more data from TCGA

query_meth <- GDCquery(
    project = "TCGA-COAD",
    data.category = "DNA Methylation",
    platform = "Illumina Human Methylation 450"
)
--------------------------------------
o GDCquery: Searching in GDC database
--------------------------------------
Genome of reference: hg38
--------------------------------------------
oo Accessing GDC. This might take a while...
--------------------------------------------
ooo Project: TCGA-COAD
--------------------
oo Filtering results
--------------------
ooo By platform
----------------
oo Checking data
----------------
ooo Checking if there are duplicated cases
Warning: There are more than one file for the same case. Please verify query results. You can use the command View(getResults(query)) in rstudio
ooo Checking if there are results for the query
-------------------
o Preparing output
-------------------
GDCdownload(query_meth)
data_type in query
Masked Intensities
Methylation Beta Value
Error in GDCdownload(query_meth) : 
  We can only download one data type. Please use data.type argument in GDCquery to filter results.
LS0tCnRpdGxlOiAiVGVzdGluZyBDb250cm9scyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKSG93IHRvIGludGVyZmFjZSB3aXRoIFRDR0EKaHR0cHM6Ly9iaW9jb25kdWN0b3Iub3JnL3BhY2thZ2VzL2RldmVsL2Jpb2MvdmlnbmV0dGVzL1RDR0FiaW9saW5rcy9pbnN0L2RvYy9pbmRleC5odG1sCmh0dHBzOi8vYmlvY29uZHVjdG9yLm9yZy9wYWNrYWdlcy9yZWxlYXNlL3dvcmtmbG93cy92aWduZXR0ZXMvVENHQVdvcmtmbG93L2luc3QvZG9jL1RDR0FXb3JrZmxvdy5odG1sI0Vudmlyb25tZW50CgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KG1pbmZpKQpsaWJyYXJ5KHNlc2FtZSkKbGlicmFyeShwaGVhdG1hcCkKbGlicmFyeShtaW5maURhdGEpCmxpYnJhcnkoRmxvd1NvcnRlZC5CbG9vZC5FUElDKQpsaWJyYXJ5KEhpVElNRUQpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShJbGx1bWluYUh1bWFuTWV0aHlsYXRpb25FUElDYW5uby5pbG0xMGI0LmhnMTkpCmxpYnJhcnkoSWxsdW1pbmFIdW1hbk1ldGh5bGF0aW9uRVBJQ3YybWFuaWZlc3QpCmxpYnJhcnkoSWxsdW1pbmFIdW1hbk1ldGh5bGF0aW9uRVBJQ3YyYW5uby4yMGExLmhnMzgpCmxpYnJhcnkoSWxsdW1pbmFIdW1hbk1ldGh5bGF0aW9uRVBJQ21hbmlmZXN0KQpsaWJyYXJ5KGxpbW1hKQpsaWJyYXJ5KHF2YWx1ZSkKbGlicmFyeShzdmEpCmxpYnJhcnkoRU5taXgpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShnZ3JlcGVsKQpsaWJyYXJ5KG1hdHJpeFN0YXRzKQpsaWJyYXJ5KEVwaURJU0gpCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KG1ldGh5bEdTQSkKYGBgCgpMb2FkaW5nIHRoZSBhbm5vdGF0aW9uIGZpbGU6CmBgYHtyfQpkYXRhKCJJbGx1bWluYUh1bWFuTWV0aHlsYXRpb25FUElDYW5uby5pbG0xMGI0LmhnMTkiKQphbm5vIDwtIGdldEFubm90YXRpb24oSWxsdW1pbmFIdW1hbk1ldGh5bGF0aW9uRVBJQ2Fubm8uaWxtMTBiNC5oZzE5KQpsb2FkKCIvVXNlcnMvYWRpYWxsby9EZXNrdG9wL0RhcnRtb3V0aC9DaHJpc3RpYW5zZW5fbGFiL0NGX1Byb2plY3QvTWV0aHlsYXRpb24vQW5ub3RhdGlvbi9FUElDLmhnMTkubWFuaWZlc3QuUkRBVEEiKQphdHRhY2goYW5ub3RhdGlvbikKbWFuaWZlc3QgPC0gZ2V0TWFuaWZlc3QoSWxsdW1pbmFIdW1hbk1ldGh5bGF0aW9uRVBJQ21hbmlmZXN0KQoKYGBgCgpMb2FkaW5nIHRoZSBkYXRhIGFuZCBtZXRhZGF0YSBpbmZvcm1hdGlvbgpgYGB7cn0KdGFyZ2V0cyA8LSByZWFkLmNzdigiL1VzZXJzL2FkaWFsbG8vRGVza3RvcC9UaGVzaXMvRGF0YV9Eb2N1bWVudHMvZG1fNTdfc2FtcGxlcy5jc3YiKQp0YXJnZXRzJHBhdGllbnQgPC0gcGFzdGUodGFyZ2V0cyRTZW50cml4X0lELHRhcmdldHMkU2VudHJpeF9Qb3NpdGlvbixzZXA9Il8iKQpyb3duYW1lcyh0YXJnZXRzKSA8LSB0YXJnZXRzJHBhdGllbnQKdGFyZ2V0cyRTYW1wbGVJRDwtIHRhcmdldHMkcGF0aWVudAoKdGFyZ2V0c19leHBhbmRlZCA8LSByZWFkLmNzdigiL1VzZXJzL2FkaWFsbG8vRGVza3RvcC9UaGVzaXMvRGF0YV9Eb2N1bWVudHMvZGF0YV9hbGwuY3N2IikKdGFyZ2V0c19leHBhbmRlZCRwYXRpZW50IDwtIHBhc3RlKHRhcmdldHMkU2VudHJpeF9JRCx0YXJnZXRzJFNlbnRyaXhfUG9zaXRpb24sc2VwPSJfIikKcm93bmFtZXModGFyZ2V0c19leHBhbmRlZCkgPC0gdGFyZ2V0c19leHBhbmRlZCRwYXRpZW50CnRhcmdldHNfZXhwYW5kZWQkU2FtcGxlSUQ8LSB0YXJnZXRzX2V4cGFuZGVkJHBhdGllbnQKdGFyZ2V0cyA9IHRhcmdldHNfZXhwYW5kZWQKYGBgCgpgYGB7cn0KaWRhdCA9ICIvVXNlcnMvYWRpYWxsby9EZXNrdG9wL1RoZXNpcy9EYXRhX0RvY3VtZW50cy9BbGxfRGF0YS9ETkFfTWV0aHlsYXRpb24vZG1fZGF0YS9ub19tYXRjaC8iClJHc2V0XzMyID0gcmVhZC5tZXRoYXJyYXkuZXhwKCIvVXNlcnMvYWRpYWxsby9EZXNrdG9wL1RoZXNpcy9EYXRhX0RvY3VtZW50cy9BbGxfRGF0YS9ETkFfTWV0aHlsYXRpb24vZG1fZGF0YS9ub19tYXRjaC9pZGF0cy8iLHJlY3Vyc2l2ZSA9IFRSVUUpIAojUkdzZXRfMjUgPSBvcGVuU2VzYW1lKGlkYXQgLCBmdW5jID0gZ2V0QmV0YXMpIApSR3NldF8yNSA9IHJlYWQubWV0aGFycmF5LmV4cCgiL1VzZXJzL2FkaWFsbG8vRGVza3RvcC9UaGVzaXMvRGF0YV9Eb2N1bWVudHMvQWxsX0RhdGEvRE5BX01ldGh5bGF0aW9uL2RtX2RhdGEvbm9fbWF0Y2gvMjVfc2FtcGxlcy8iLHJlY3Vyc2l2ZSA9IFRSVUUpIApgYGAKCk5vcm1hbGl6ZSBteSBEYXRhCmBgYHtyfQpOb29iXzI1X20gPSBwcmVwcm9jZXNzTm9vYihSR3NldF8yNSkKTm9vYl8zMl9tID0gcHJlcHJvY2Vzc05vb2IoUkdzZXRfMzIpCmBgYAoKR2V0dGluZyB0aGUgYmV0YSB2YWx1ZXMKYGBge3J9CkJldGFzXzI1PC1nZXRCZXRhKE5vb2JfMjVfbSkKQmV0YXNfMzI8LWdldEJldGEoTm9vYl8zMl9tKQpgYGAKCmBgYHtyfQpCZXRhc18yNTwtIHNlc2FtZTo6YmV0YXNDb2xsYXBzZVRvUGZ4KEJldGFzXzI1KQojQmV0YXNfMzI8LSBzZXNhbWU6OmJldGFzQ29sbGFwc2VUb1BmeChCZXRhc18zMikKY29sbmFtZXMoQmV0YXNfMjUpID0gY29sbmFtZXMoTm9vYl8yNV9tKQpgYGAKCmBgYHtyfQpESF9DUkNfQmV0YXMgPC0gbWVyZ2UoQmV0YXNfMjUsIEJldGFzXzMyLCBieSA9ICJyb3cubmFtZXMiKQpyb3duYW1lcyhESF9DUkNfQmV0YXMpIDwtIERIX0NSQ19CZXRhcyRSb3cubmFtZXMKREhfQ1JDX0JldGFzIDwtIERIX0NSQ19CZXRhc1ssLTFdIApgYGAKCgpSdW5uaW5nIEVwaURpc2ggdG8gb2J0YWluIEZpYnJvYmxhc3QgaW5mb3JtYXRpb24KYGBge3J9CiMgRGVmaW5lIHRoZSBiZXRhIG1hdHJpeCBhbmQgcmVmZXJlbmNlIG1hdHJpeApiZXRhX21hdHJpeCA8LSBESF9DUkNfQmV0YXMgICMgWW91ciBkYXRhc2V0CnJlZl9tYXRyaXggPC0gY2VudEVwaUZpYklDLm0gICMgUmVmZXJlbmNlIG1hdHJpeCBmb3IgRXBpRElTSCAoZS5nLiwgY2VudEVwaUZpYklDLm0pCgojIFJ1biBFcGlESVNICmVwaWRpc2hfcmVzdWx0cyA8LSBlcGlkaXNoKGJldGEubSA9IGJldGFfbWF0cml4LCByZWYubSA9IHJlZl9tYXRyaXgsIG1ldGhvZCA9ICJSUEMiKQoKIyBFeHRyYWN0IHRoZSBlc3RpbWF0ZWQgY2VsbCB0eXBlIHByb3BvcnRpb25zCmNlbGxfdHlwZV9wcm9wb3J0aW9ucyA8LSBlcGlkaXNoX3Jlc3VsdHMkZXN0RgoKIyBDb252ZXJ0IHRoZSBtYXRyaXggdG8gYSBkYXRhIGZyYW1lIGFuZCBzY2FsZSBwcm9wb3J0aW9ucyB0byBwZXJjZW50YWdlcwpjZWxsX3R5cGVfcHJvcG9ydGlvbnNfZGYgPC0gYXMuZGF0YS5mcmFtZShjZWxsX3R5cGVfcHJvcG9ydGlvbnMpICogMTAwCgojIEFkZCBTYW1wbGVJRCBhcyBhIGNvbHVtbiBmcm9tIHRoZSByb3cgbmFtZXMKY2VsbF90eXBlX3Byb3BvcnRpb25zX2RmJFNhbXBsZUlEIDwtIHJvd25hbWVzKGNlbGxfdHlwZV9wcm9wb3J0aW9ucykKCiMgSW5zcGVjdCB0aGUgcmVzdWx0cwpoZWFkKGNlbGxfdHlwZV9wcm9wb3J0aW9uc19kZikKYGBgCgoKUnVubmluZyBIaVRJTUVEIHRvIGdlbmVyYXRlIGNlbGwgdHlwZSBwcm9wb3J0aW9ucwpgYGB7cn0KSGlUSU1FRF9yZXN1bHQ8LUhpVElNRURfZGVjb252b2x1dGlvbihESF9DUkNfQmV0YXMsIkNPQUQiLDUsInR1bW9yIikKCkhpVElNRURfcmVzdWx0JFNhbXBsZUlEIDwtIHJvd25hbWVzKEhpVElNRURfcmVzdWx0KQoKSGlUSU1FRF9yZXN1bHRfaW1tdW5lPC1IaVRJTUVEX2RlY29udm9sdXRpb24oREhfQ1JDX0JldGFzLCJDT0FEIiwyLCJ0dW1vciIpCgpIaVRJTUVEX3Jlc3VsdF9pbW11bmUkU2FtcGxlSUQgPC0gcm93bmFtZXMoSGlUSU1FRF9yZXN1bHQpCmBgYAoKCkdldCBHVEV4IGRhdGEKYGBge3J9CgpCZXRhc19HVEV4ID0gcmVhZFJEUygiL1VzZXJzL2FkaWFsbG8vRGVza3RvcC9UaGVzaXMvRGF0YV9Eb2N1bWVudHMvQWxsX0RhdGEvRE5BX01ldGh5bGF0aW9uL2RtX2RhdGEvR1RFeC9HVEV4X3NhbXBsZXMucmRzIikKdGFyZ2V0c19HVEV4IDwtIHJlYWQuY3N2KCIvVXNlcnMvYWRpYWxsby9EZXNrdG9wL1RoZXNpcy9EYXRhX0RvY3VtZW50cy9BbGxfRGF0YS9ETkFfTWV0aHlsYXRpb24vZG1fZGF0YS9HVEV4L3RhcmdldHMuY3N2IikKdGFyZ2V0c19HVEV4JHBhdGllbnQgPC0gdGFyZ2V0c19HVEV4JEZpbGVuYW1lCnJvd25hbWVzKHRhcmdldHNfR1RFeCkgPC0gdGFyZ2V0c19HVEV4JHBhdGllbnQKdGFyZ2V0c19HVEV4JFNhbXBsZUlEPC0gdGFyZ2V0c19HVEV4JHBhdGllbnQKCiMgLS0tIEhhcm1vbml6ZSBDcEdzIC0tLQpjb21tb25fY3Bnc19HVEV4IDwtIGludGVyc2VjdChyb3duYW1lcyhCZXRhc19HVEV4KSwgcm93bmFtZXMoY2VudEVwaUZpYklDLm0pKQpiZXRhc19HVEV4X2ZpbHRlcmVkIDwtIEJldGFzX0dURXhbY29tbW9uX2NwZ3NfR1RFeCwgXQpyZWZfZmlsdGVyZWRfR1RFeCA8LSBjZW50RXBpRmliSUMubVtjb21tb25fY3Bnc19HVEV4LCBdCiAgCiMgLS0tIFJ1biBFcGlESVNIIC0tLQplcGlkaXNoX0dURXggPC0gZXBpZGlzaChiZXRhLm0gPSBiZXRhc19HVEV4X2ZpbHRlcmVkLCByZWYubSA9IHJlZl9maWx0ZXJlZF9HVEV4LCBtZXRob2QgPSAiUlBDIikKY2VsbF9wcm9wc19HVEV4IDwtIGFzLmRhdGEuZnJhbWUoZXBpZGlzaF9HVEV4JGVzdEYpICogMTAwCmNlbGxfcHJvcHNfR1RFeCRTYW1wbGVJRCA8LSByb3duYW1lcyhjZWxsX3Byb3BzX0dURXgpCgojIE9wdGlvbmFsOiBNZXJnZSB3aXRoIG1ldGFkYXRhCmNlbGxfcHJvcHNfR1RFeCA8LSBtZXJnZShjZWxsX3Byb3BzX0dURXgsIHRhcmdldHNfR1RFeCwgYnkgPSAiU2FtcGxlSUQiKQoKSGlUSU1FRF9yZXN1bHRfR1RFeDwtSGlUSU1FRF9kZWNvbnZvbHV0aW9uKEJldGFzX0dURXgsIkNPQUQiLGggPSA1LCJ0dW1vciIpCgpIaVRJTUVEX3Jlc3VsdF9HVEV4JFNhbXBsZUlEIDwtIHJvd25hbWVzKEhpVElNRURfcmVzdWx0X0dURXgpCgpIaVRJTUVEX3Jlc3VsdF9pbW11bmVfR1RFeDwtSGlUSU1FRF9kZWNvbnZvbHV0aW9uKEJldGFzX0dURXgsIkNPQUQiLGggPSAyLCJ0dW1vciIpCgpIaVRJTUVEX3Jlc3VsdF9pbW11bmVfR1RFeCRTYW1wbGVJRCA8LSByb3duYW1lcyhIaVRJTUVEX3Jlc3VsdF9HVEV4KQoKYGBgCgpHZXQgVENHQSBkYXRhCgpgYGB7cn0KdGNnYS5kYXRhIDwtIHJlYWRSRFMoIi9Vc2Vycy9hZGlhbGxvL0Rlc2t0b3AvVGhlc2lzL0RhdGFfRG9jdW1lbnRzL0FsbF9EYXRhL0ROQV9NZXRoeWxhdGlvbi9kbV9kYXRhL1RDR0EvVENHQV9kYXRhLnJkcyIpCnRjZ2EuZG5hbSA8LSB0Y2dhLmRhdGFbWyJkbmFtIl1dCnRjZ2EucGhlbm8gPC0gdGNnYS5kYXRhW1sicGhlbm8iXV0KdGNnYS5jZWxsIDwtIHRjZ2EuZGF0YVtbImNlbGxfdHlwZXMiXV0KbXNpX2RhdDwtcmVhZFJEUygiL1VzZXJzL2FkaWFsbG8vRGVza3RvcC9UaGVzaXMvRGF0YV9Eb2N1bWVudHMvQWxsX0RhdGEvRE5BX01ldGh5bGF0aW9uL2RtX2RhdGEvVENHQS9tc2lfdGNnYS5yZHMiKQp0Y2dhLmNlbGwkQ09BRF9EZWNvbnYxIyRNU1MKdGNnYS5jZWxsJENPQURfRGVjb252MiNNQVNTCgp0Y2dhX1QgPSB0KHRjZ2EuZG5hbSkKCiMgVHJhbnNwb3NlIGJhY2sgdG8gcCB4IG4gZm9yIEVwaURJU0ggKHJvd3MgPSBDcEdzKQp0Y2dhX1RfYmV0YSA8LSB0KHRjZ2FfVCkKCiMgRW5zdXJlIHlvdSdyZSB1c2luZyB0Y2dhX1QgYXMgaXMsIG5vdCB0cmFuc3Bvc2VkIGFnYWluCmNvbW1vbl9jcGdzX1RDR0EgPC0gaW50ZXJzZWN0KHJvd25hbWVzKHRjZ2FfVCksIHJvd25hbWVzKGNlbnRFcGlGaWJJQy5tKSkKYmV0YXNfVENHQV9maWx0ZXJlZCA8LSB0Y2dhX1RbY29tbW9uX2NwZ3NfVENHQSwgXQpyZWZfZmlsdGVyZWRfVENHQSA8LSBjZW50RXBpRmliSUMubVtjb21tb25fY3Bnc19UQ0dBLCBdCgojIFJ1biBFcGlESVNICmVwaWRpc2hfVENHQSA8LSBlcGlkaXNoKGJldGEubSA9IGJldGFzX1RDR0FfZmlsdGVyZWQsIHJlZi5tID0gcmVmX2ZpbHRlcmVkX1RDR0EsIG1ldGhvZCA9ICJSUEMiKQpjZWxsX3Byb3BzX1RDR0EgPC0gYXMuZGF0YS5mcmFtZShlcGlkaXNoX1RDR0EkZXN0RikgKiAxMDAKY2VsbF9wcm9wc19UQ0dBJFNhbXBsZUlEIDwtIHJvd25hbWVzKGNlbGxfcHJvcHNfVENHQSkKCiMgT3B0aW9uYWw6IE1lcmdlIHdpdGggVENHQSBwaGVub3R5cGUgZGF0YQp0Y2dhLnBoZW5vJFNhbXBsZUlEIDwtIHJvd25hbWVzKHRjZ2EucGhlbm8pCgpjZWxsX3Byb3BzX1RDR0EgPC0gbWVyZ2UoCiAgY2VsbF9wcm9wc19UQ0dBLAogIHRjZ2EucGhlbm8sCiAgYnkgPSAiU2FtcGxlSUQiCikKI2NlbGxfcHJvcHNfVENHQSA8LSBtZXJnZShjZWxsX3Byb3BzX1RDR0EsIHRjZ2EucGhlbm8sIGJ5ID0gIlNhbXBsZUlEIikKCkhpVElNRURfcmVzdWx0X1RDR0E8LUhpVElNRURfZGVjb252b2x1dGlvbih0dW1vcl9iZXRhID0gdGNnYV9ULHR1bW9yX3R5cGUgPSAiQ09BRCIsaCA9IDUpCgpIaVRJTUVEX3Jlc3VsdF9UQ0dBJFNhbXBsZUlEIDwtIHJvd25hbWVzKEhpVElNRURfcmVzdWx0X1RDR0EpCgpIaVRJTUVEX3Jlc3VsdF9pbW11bmVfVENHQTwtSGlUSU1FRF9kZWNvbnZvbHV0aW9uKHR1bW9yX2JldGEgPSB0Y2dhX1QsdHVtb3JfdHlwZSA9ICJDT0FEIixoID0gMikKCkhpVElNRURfcmVzdWx0X2ltbXVuZV9UQ0dBJFNhbXBsZUlEIDwtIHJvd25hbWVzKEhpVElNRURfcmVzdWx0X1RDR0EpCgpgYGAKCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGdncHVicikKCiMgLS0tLSBGdW5jdGlvbiB0byBSZXNoYXBlIERhdGEgLS0tLQpleHRyYWN0X3N1YnNldCA8LSBmdW5jdGlvbihkZiwgc291cmNlX2xhYmVsLCBjZWxsX3R5cGVzID0gYygiQ0Q4VCIsICJUdW1vciIsICJFcGl0aGVsaWFsIikpIHsKICBkZiAlPiUKICAgIHNlbGVjdChhbGxfb2YoY2VsbF90eXBlcyksIFNhbXBsZUlEKSAlPiUKICAgIHBpdm90X2xvbmdlcigtU2FtcGxlSUQsIG5hbWVzX3RvID0gIkNlbGxUeXBlIiwgdmFsdWVzX3RvID0gIlByb3BvcnRpb24iKSAlPiUKICAgIG11dGF0ZShTb3VyY2UgPSBzb3VyY2VfbGFiZWwpCn0KCiMgLS0tLSBDb21iaW5lIERhdGFzZXRzIC0tLS0KZGZfREggPC0gZXh0cmFjdF9zdWJzZXQoSGlUSU1FRF9yZXN1bHQsICJESCIpCmRmX0dURXggPC0gZXh0cmFjdF9zdWJzZXQoSGlUSU1FRF9yZXN1bHRfR1RFeCwgIkdURXgiKQpkZl9UQ0dBIDwtIGV4dHJhY3Rfc3Vic2V0KEhpVElNRURfcmVzdWx0X1RDR0EsICJUQ0dBIikKCmNvbWJpbmVkX2RmIDwtIGJpbmRfcm93cyhkZl9ESCwgZGZfR1RFeCwgZGZfVENHQSkKCiMgLS0tLSBEZWZpbmUgY29tcGFyaXNvbnMgLS0tLQpjb21wYXJpc29ucyA8LSBsaXN0KGMoIkRIIiwgIkdURXgiKSwgYygiREgiLCAiVENHQSIpKQoKIyAtLS0tIEJveHBsb3Qgd2l0aCBTaWduaWZpY2FuY2UgQW5ub3RhdGlvbnMgLS0tLQpnZ3Bsb3QoY29tYmluZWRfZGYsIGFlcyh4ID0gU291cmNlLCB5ID0gUHJvcG9ydGlvbiwgZmlsbCA9IFNvdXJjZSkpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5zaGFwZSA9IE5BLCB3aWR0aCA9IDAuNykgKwogIGZhY2V0X3dyYXAofiBDZWxsVHlwZSwgc2NhbGVzID0gImZyZWVfeSIpICsKICBzdGF0X2NvbXBhcmVfbWVhbnMoY29tcGFyaXNvbnMgPSBjb21wYXJpc29ucywgbWV0aG9kID0gIndpbGNveC50ZXN0IiwKICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAicC5zaWduaWYiLCBoaWRlLm5zID0gVFJVRSkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsKICBsYWJzKHRpdGxlID0gIkNlbGwgVHlwZSBQcm9wb3J0aW9ucyBBY3Jvc3MgRGF0YXNldHMiLAogICAgICAgeSA9ICJFc3RpbWF0ZWQgUHJvcG9ydGlvbiIsCiAgICAgICB4ID0gIkRhdGFzZXQiKSArCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAxNCkgKwogIHRoZW1lKHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9IDEpKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoZ2dwdWJyKQoKIyAtLS0tIEZ1bmN0aW9uIHRvIEV4dHJhY3QgQ2VsbCBUeXBlcyAtLS0tCmV4dHJhY3Rfc3Vic2V0IDwtIGZ1bmN0aW9uKGRmLCBzb3VyY2VfbGFiZWwsIGNlbGxfdHlwZXMgPSBjKCJDRDhUIiwgIlR1bW9yIiwgIkVwaXRoZWxpYWwiKSkgewogIGRmICU+JQogICAgc2VsZWN0KGFsbF9vZihjZWxsX3R5cGVzKSwgU2FtcGxlSUQpICU+JQogICAgcGl2b3RfbG9uZ2VyKC1TYW1wbGVJRCwgbmFtZXNfdG8gPSAiQ2VsbFR5cGUiLCB2YWx1ZXNfdG8gPSAiUHJvcG9ydGlvbiIpICU+JQogICAgbXV0YXRlKFNvdXJjZSA9IHNvdXJjZV9sYWJlbCkKfQoKIyAtLS0tIENvbWJpbmUgT25seSBESCBhbmQgR1RFeCAtLS0tCmRmX0RIIDwtIGV4dHJhY3Rfc3Vic2V0KEhpVElNRURfcmVzdWx0LCAiREgiKQpkZl9HVEV4IDwtIGV4dHJhY3Rfc3Vic2V0KEhpVElNRURfcmVzdWx0X0dURXgsICJHVEV4IikKCmNvbWJpbmVkX2RmIDwtIGJpbmRfcm93cyhkZl9ESCwgZGZfR1RFeCkKCiMgLS0tLSBEZWZpbmUgQ29tcGFyaXNvbnMgLS0tLQpjb21wYXJpc29ucyA8LSBsaXN0KGMoIkRIIiwgIkdURXgiKSkKCiMgLS0tLSBQbG90IC0tLS0KZ2dwbG90KGNvbWJpbmVkX2RmLCBhZXMoeCA9IFNvdXJjZSwgeSA9IFByb3BvcnRpb24sIGZpbGwgPSBTb3VyY2UpKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuc2hhcGUgPSBOQSwgd2lkdGggPSAwLjcpICsKICBmYWNldF93cmFwKH4gQ2VsbFR5cGUsIHNjYWxlcyA9ICJmcmVlX3kiKSArCiAgc3RhdF9jb21wYXJlX21lYW5zKGNvbXBhcmlzb25zID0gY29tcGFyaXNvbnMsIG1ldGhvZCA9ICJ3aWxjb3gudGVzdCIsCiAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gInAuc2lnbmlmIiwgaGlkZS5ucyA9IFRSVUUpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArCiAgbGFicyh0aXRsZSA9ICJDb21wYXJpc29uIG9mIENlbGwgVHlwZSBQcm9wb3J0aW9uczogREggdnMgR1RFeCIsCiAgICAgICB5ID0gIkVzdGltYXRlZCBQcm9wb3J0aW9uIiwKICAgICAgIHggPSAiRGF0YXNldCIpICsKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDE0KSArCiAgdGhlbWUoc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSkpCmBgYAoKCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoZ2dwdWJyKQoKIyAtLS0tIEZ1bmN0aW9uIHRvIEV4dHJhY3QgSGlUSU1FRCBDZWxsIFR5cGVzIC0tLS0KZXh0cmFjdF9zdWJzZXRfaGl0aW1lZCA8LSBmdW5jdGlvbihkZiwgc291cmNlX2xhYmVsLCBjZWxsX3R5cGVzID0gYygiQ0Q4VCIsICJUdW1vciIsICJFcGl0aGVsaWFsIikpIHsKICBkZiAlPiUKICAgIHNlbGVjdChhbGxfb2YoY2VsbF90eXBlcyksIFNhbXBsZUlEKSAlPiUKICAgIHBpdm90X2xvbmdlcigtU2FtcGxlSUQsIG5hbWVzX3RvID0gIkNlbGxUeXBlIiwgdmFsdWVzX3RvID0gIlByb3BvcnRpb24iKSAlPiUKICAgIG11dGF0ZShTb3VyY2UgPSBzb3VyY2VfbGFiZWwpCn0KCiMgLS0tLSBFeHRyYWN0IEhpVElNRUQgUmVzdWx0cyBmb3IgREggYW5kIEdURXggLS0tLQpkZl9ESF9oaXRpbWVkIDwtIGV4dHJhY3Rfc3Vic2V0X2hpdGltZWQoSGlUSU1FRF9yZXN1bHQsICJESCIpCmRmX0dURXhfaGl0aW1lZCA8LSBleHRyYWN0X3N1YnNldF9oaXRpbWVkKEhpVElNRURfcmVzdWx0X0dURXgsICJHVEV4IikKCiMgLS0tLSBGdW5jdGlvbiB0byBFeHRyYWN0IEZpYnJvYmxhc3QgRXN0aW1hdGVzIGZyb20gRXBpRElTSC9FcGlTY29yZSAtLS0tCmV4dHJhY3Rfc3Vic2V0X2ZpYiA8LSBmdW5jdGlvbihlcGlfZGYsIHNvdXJjZV9sYWJlbCkgewogIGVwaV9kZiAlPiUgCiAgICBzZWxlY3QoRmliLCBTYW1wbGVJRCkgJT4lIAogICAgcGl2b3RfbG9uZ2VyKC1TYW1wbGVJRCwgbmFtZXNfdG8gPSAiQ2VsbFR5cGUiLCB2YWx1ZXNfdG8gPSAiUHJvcG9ydGlvbiIpICU+JSAKICAgIG11dGF0ZShTb3VyY2UgPSBzb3VyY2VfbGFiZWwpCn0KCiMgLS0tLSBFeHRyYWN0IEZpYnJvYmxhc3QgUmVzdWx0cyBmb3IgREggYW5kIEdURXggLS0tLQpkZl9ESF9maWIgPC0gZXh0cmFjdF9zdWJzZXRfZmliKGNlbGxfdHlwZV9wcm9wb3J0aW9uc19kZiwgIkRIIikKZGZfR1RFeF9maWIgPC0gZXh0cmFjdF9zdWJzZXRfZmliKGNlbGxfcHJvcHNfR1RFeCwgIkdURXgiKQoKIyAtLS0tIENvbWJpbmUgQWxsIFJlc3VsdHMgLS0tLQpjb21iaW5lZF9kZiA8LSBiaW5kX3Jvd3MoZGZfREhfaGl0aW1lZCwgZGZfR1RFeF9oaXRpbWVkLCBkZl9ESF9maWIsIGRmX0dURXhfZmliKQoKIyAtLS0tIERlZmluZSBDb21wYXJpc29ucyAoREggdnMgR1RFeCBmb3IgZWFjaCBjZWxsIHR5cGUpIC0tLS0KY29tcGFyaXNvbnMgPC0gbGlzdChjKCJESCIsICJHVEV4IikpCgojIC0tLS0gUGxvdDogRmFjZXRlZCBCb3hwbG90cyBieSBDZWxsVHlwZSAtLS0tCmdncGxvdChjb21iaW5lZF9kZiwgYWVzKHggPSBTb3VyY2UsIHkgPSBQcm9wb3J0aW9uLCBmaWxsID0gU291cmNlKSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLnNoYXBlID0gTkEsIHdpZHRoID0gMC43KSArCiAgZmFjZXRfd3JhcCh+IENlbGxUeXBlLCBzY2FsZXMgPSAiZnJlZV95IikgKwogIHN0YXRfY29tcGFyZV9tZWFucyhjb21wYXJpc29ucyA9IGNvbXBhcmlzb25zLCBtZXRob2QgPSAid2lsY294LnRlc3QiLAogICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICJwLnNpZ25pZiIsIGhpZGUubnMgPSBUUlVFKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikgKwogIGxhYnModGl0bGUgPSAiQ29tcGFyaXNvbiBvZiBDZWxsIFR5cGUgUHJvcG9ydGlvbnM6IERIIHZzIEdURXgiLAogICAgICAgeSA9ICJFc3RpbWF0ZWQgUHJvcG9ydGlvbiAoJSkiLAogICAgICAgeCA9ICJEYXRhc2V0IikgKwogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMTQpICsKICB0aGVtZShzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSkKYGBgCgoKCkZvciBvYnRhaW5pbmcgbW9yZSBkYXRhIGZyb20gVENHQQpgYGB7cn0KbGlicmFyeShUQ0dBYmlvbGlua3MpCgojIFNwZWNpZnkgdGhlIGV4YWN0IGRhdGEgdHlwZSAodXN1YWxseSBiZXRhLXZhbHVlcykKcXVlcnkubWV0IDwtIEdEQ3F1ZXJ5KAogIHByb2plY3QgPSAiVENHQS1DT0FEIiwKICBkYXRhLmNhdGVnb3J5ID0gIkROQSBNZXRoeWxhdGlvbiIsCiAgZGF0YS50eXBlID0gIk1ldGh5bGF0aW9uIEJldGEgVmFsdWUiLAogIHBsYXRmb3JtID0gIklsbHVtaW5hIEh1bWFuIE1ldGh5bGF0aW9uIDQ1MCIKKQoKZmlsZXMgPC0gZ2V0UmVzdWx0cyhxdWVyeS5tZXQpCmhlYWQoZmlsZXMkZmlsZV9pZCkKIyBEb3dubG9hZCB0aGUgZGF0YQpHRENkb3dubG9hZChxdWVyeS5tZXQsIGZpbGVzLnBlci5jaHVuayA9IDIwKQoKIyBQcmVwYXJlIGRhdGEgZm9yIGFuYWx5c2lzCmRhdGEubWV0IDwtIEdEQ3ByZXBhcmUocXVlcnkubWV0KQoKbGlicmFyeShTdW1tYXJpemVkRXhwZXJpbWVudCkKCm1hdCA9IGFzc2F5KGRhdGEubWV0KQpkZiA9IGFzLmRhdGEuZnJhbWUobWF0KQpkZiRjcGcgPC0gcm93bmFtZXMoZGYpCmRmIDwtIGRmWyxjKCJjcGciLHNldGRpZmYoY29sbmFtZXMoZGYpLCJjcGciKSldCgoKI0hvdyB0byBnZXQgdGhlIGNsaW5pY2FsIGRhdGEKcXVlcnlfY2xpbmljYWwgPC0gR0RDcXVlcnkoCiAgICBwcm9qZWN0ID0gIlRDR0EtQ09BRCIsIAogICAgZGF0YS5jYXRlZ29yeSA9ICJDbGluaWNhbCIsCiAgICBkYXRhLnR5cGUgPSAiQ2xpbmljYWwgU3VwcGxlbWVudCIsIAogICAgZGF0YS5mb3JtYXQgPSAiQkNSIEJpb3RhYiIKKQoKR0RDZG93bmxvYWQocXVlcnlfY2xpbmljYWwpCgpjbGluaWNhbC5CQ1J0YWIuYWxsIDwtIEdEQ3ByZXBhcmUocXVlcnlfY2xpbmljYWwpCm5hbWVzKGNsaW5pY2FsLkJDUnRhYi5hbGwpCgpkcGx5cjo6Z2xpbXBzZShjbGluaWNhbC5CQ1J0YWIuYWxsJGNsaW5pY2FsX3BhdGllbnRfY29hZCkKCnF1ZXJ5X21ldGggPC0gR0RDcXVlcnkoCiAgICBwcm9qZWN0ID0gIlRDR0EtQ09BRCIsCiAgICBkYXRhLmNhdGVnb3J5ID0gIkROQSBNZXRoeWxhdGlvbiIsCiAgICBwbGF0Zm9ybSA9ICJJbGx1bWluYSBIdW1hbiBNZXRoeWxhdGlvbiA0NTAiCikKR0RDZG93bmxvYWQocXVlcnlfbWV0aCkKbWV0aF9kYXRhIDwtIEdEQ3ByZXBhcmUocXVlcnlfbWV0aCkKbWV0aF9iYXJjb2RlcyA8LSBzdWJzdHIoY29sbmFtZXMobWV0aF9kYXRhKSwgMSwgMTIpCmBgYAoK